#include "write_buffer.hh"
#include <cstring>

namespace kratos {
namespace util {

WriteBuffer::WriteBuffer(std::size_t capacity) {
  length_ = capacity;
  buf_ = std::make_unique<char[]>(length_);
}

WriteBuffer::~WriteBuffer() {}

auto WriteBuffer::write(const char *data, std::size_t length)
    -> std::pair<const char *, std::size_t> {
  if (length + size_ > length_) {
    length_ += length;
    auto tmp = std::make_unique<char[]>(length_);
    std::memcpy(tmp.get(), buf_.get(), size_);
    buf_.swap(tmp);
  }
  auto tmp_size = size_;
  std::memcpy(buf_.get() + size_, data, length);
  size_ += length;
  return {buf_.get() + tmp_size, length};
}

auto WriteBuffer::apply(std::size_t length) -> std::pair<char *, std::size_t> {
  if (length + size_ > length_) {
    length_ += length;
    auto tmp = std::make_unique<char[]>(length_);
    if (!tmp) {
      return {nullptr, 0};
    }
    std::memcpy(tmp.get(), buf_.get(), size_);
    buf_.swap(tmp);
  }
  auto tmp_size = size_;
  size_ += length;
  return {buf_.get() + tmp_size, length};
}

auto WriteBuffer::length() -> std::size_t { return size_; }

auto WriteBuffer::get() -> const char * { return buf_.get(); }

auto WriteBuffer::clear() -> void { size_ = 0; }

} // namespace util
} // namespace kratos
